package karma.pool.util.clock;

/**
 * ClockFactory is used to create a platform-specific Clock.
 */
public class ClockFactory {
   public static final Clock CLOCK = create();

   public static Clock create() {
      String os = System.getProperty("os.name");
      if ("Mac OS X".equals(os)) {
         return new MilliSecondClock();
      }
      return new NanoSecondClock();
   }

   /**
    * Get the current time-stamp (resolution is opaque).
    *
    * @return the current time-stamp
    */
   public static long currentTime() {
      return CLOCK.currentTime();
   }

   /**
    * Return the specified opaque time-stamp plus the specified number of milliseconds.
    *
    * @param time   an opaque time-stamp
    * @param millis milliseconds to add
    * @return a new opaque time-stamp
    */
   public static long plusMillis(long time, long millis) {
      return CLOCK.plusMillis(time, millis);
   }

   /**
    * Get a String representation of the elapsed time in appropriate magnitude terminology.
    *
    * @param startTime an opaque time-stamp
    * @param endTime   an opaque time-stamp
    * @return a string representation of the elapsed time interval
    */
   public static String elapsedDisplayString(long startTime, long endTime) {
      return CLOCK.elapsedDisplayString0(startTime, endTime);
   }

   /**
    * Get the difference in nanoseconds between two opaque time-stamps returned
    * by currentTime().
    *
    * @param startTime an opaque time-stamp returned by an instance of this class
    * @param endTime   an opaque time-stamp returned by an instance of this class
    * @return the elapsed time between startTime and endTime in nanoseconds
    */
   public static long elapsedNanos(long startTime, long endTime) {
      return CLOCK.elapsedNanos(startTime, endTime);
   }

   /**
    * Convert an opaque time-stamp returned by currentTime() into an
    * elapsed time in milliseconds, based on the current instant in time.
    *
    * @param startTime an opaque time-stamp returned by an instance of this class
    * @return the elapsed time between startTime and now in milliseconds
    */
   public static long elapsedNanos(long startTime) {
      return CLOCK.elapsedNanos(startTime);
   }

   /**
    * Get the difference in milliseconds between two opaque time-stamps returned
    * by currentTime().
    *
    * @param startTime an opaque time-stamp returned by an instance of this class
    * @param endTime   an opaque time-stamp returned by an instance of this class
    * @return the elapsed time between startTime and endTime in milliseconds
    */
   public static long elapsedMillis(long startTime, long endTime) {
      return CLOCK.elapsedMillis(startTime, endTime);
   }

   /**
    * Convert an opaque time-stamp returned by currentTime() into an
    * elapsed time in milliseconds, based on the current instant in time.
    *
    * @param startTime an opaque time-stamp returned by an instance of this class
    * @return the elapsed time between startTime and now in milliseconds
    */
   public static long elapsedMillis(long startTime) {
      return CLOCK.elapsedMillis(startTime);
   }

   /**
    * Convert an opaque time-stamp returned by currentTime() into
    * milliseconds.
    *
    * @param time an opaque time-stamp returned by an instance of this class
    * @return the time-stamp in milliseconds
    */
   public static long toMillis(long time) {
      return CLOCK.toMillis(time);
   }
}
